/*
 * CarriTelEP.java
 *
 * Created on 4 de octubre de 2006, 09:58 AM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package guru.mercurio.eps.cgi;

import guru.mercurio.common.PhoneAddress;
import guru.mercurio.common.RelativeApplicationAddress;
import guru.mercurio.data.PassportDataManager;
import guru.merlin.core.AbstractEnvelopeProcessor;
import guru.merlin.core.AddressException;
import guru.merlin.core.CantHandException;
import guru.merlin.core.ConfigurationEPException;
import guru.merlin.core.EPException;
import guru.merlin.core.Envelope;
import guru.merlin.core.PeerEPException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Properties;
import javax.net.ssl.HttpsURLConnection;
import org.apache.log4j.Logger;
import guru.mercurio.core.delivery.https.HttpsHostNameVerifier;
import guru.mercurio.core.delivery.https.HttpsX509TrustManager;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;


/**
 *
 * @author sventura
 */
public class CgiEP extends AbstractEnvelopeProcessor {
    private static Logger logger = Logger.getLogger (CgiEP.class);
    public static Properties props = new Properties ();
    //PassportDataManager pdm = null;
    
    /** Creates a new instance of CarriTelEP */
    public CgiEP () {
    }
    
    public static void main (String args[]){
        CgiEP cgi = new CgiEP ();
        try {
            cgi.openConnection ("C:\\santiago\\workspace\\netbeans\\tedexis\\Mercurio22x\\src\\guru\\mercurio\\eps\\cgi\\cgi.properties");
            String content = "Hola esto es una prueba del ep para llamar a los CGI";
            RelativeApplicationAddress r = new RelativeApplicationAddress ("carritel", "22625");
            PhoneAddress p = new PhoneAddress ("58", "416", "8123239");
            Envelope env = new Envelope (content, p, r);
            cgi.handEnvelope (env);
        } catch (EPException ex) {
            ex.printStackTrace ();
        } catch (AddressException ex) {
            ex.printStackTrace ();
        }
        
    }
    
    private URLConnection getConnection (String operatorShortName, String urlString, String login, String password, String encoding,String mensaje,String destinatarios) throws EPException {
        String direccionIn;
        URLConnection conn = null;
        try {
            login = URLEncoder.encode (login,encoding);
            password= URLEncoder.encode (password,encoding);
            mensaje= URLEncoder.encode (mensaje,encoding);
            destinatarios= URLEncoder.encode (destinatarios,encoding);
            direccionIn = urlString.concat ("?destinatarios="+destinatarios+"&mensaje="+mensaje+"&login="+login+"&password="+password);
            
            logger.info (operatorShortName+": url to be invoked=("+direccionIn+")");
            System.out.println (operatorShortName+": url to be invoked=("+direccionIn+")");
            URL url = new URL (direccionIn);
            if (direccionIn.startsWith ("https")){
                return (HttpsURLConnection)url.openConnection ();                
            } else if (direccionIn.startsWith ("http")){
                return (HttpURLConnection)url.openConnection ();
            }

        } catch (UnsupportedEncodingException ex) {
            throw new ConfigurationEPException (ex.getMessage ());
        } catch (MalformedURLException ex) {
            throw new ConfigurationEPException (ex.getMessage ());
        } catch (IOException ex) {
            throw new PeerEPException (ex.getMessage ());
        }
        
        return conn;
    }
    
    
    /*
     * (non-Javadoc)
     *
     * @see guru.merlin.core.EnvelopeProcessor#openConnection(java.lang.String)
     */
    public void openConnection (String parametersFilePath) throws EPException {
        try {
            InputStream fis = new FileInputStream (parametersFilePath);
            CgiEP.props.load (fis);
            fis.close ();
            logger.info ("Properties file loaded");
            
        } catch (IOException e) {
            e.printStackTrace ();
            logger.error ("", e);
            throw new ConfigurationEPException ("Properties file can't be loaded");
        }
        
        String driver = CgiEP.props.getProperty ("maya.db.driver");
        String dbmsURL = CgiEP.props.getProperty ("maya.db.dbmsURL");
        String username = CgiEP.props.getProperty ("maya.db.username");
        String passworddb = CgiEP.props.getProperty ("maya.db.password");
        try {
            //pdm = new PassportDataManager (driver,dbmsURL,username,passworddb);
        } catch (Exception ex) {
            throw new ConfigurationEPException ("Object PassportDataManager can't be created");
        }
    }
    
    
    
    /*
     * (non-Javadoc)
     *
     * @see guru.merlin.core.EnvelopeProcessor#closeConnection()
     */
    public void closeConnection () throws EPException {
        
    }
    
    /*
     * (non-Javadoc)
     *
     * @see guru.merlin.core.EnvelopeProcessor#start()
     */
    public void start () throws EPException{
    }
    
    /*
     * (non-Javadoc)
     *
     * @see guru.merlin.core.EnvelopeProcessor#stop()
     */
    public void stop () {
    }
    
    public boolean isConnected () {
        return true;
    }
    
    public Object handEnvelope (Envelope envelope) throws EPException {
        String msg = "";
        String tempResponse = "";
        String operatorShortName;
        String urlString;
        String login;
        String password;
        String direccionIn = null;
        String encoding;
        String mensaje;
        String destinatarios;
        
        if (props.getProperty ("operatorShortName")==null || props.getProperty ("operatorShortName").equals ("")) {
            logger.error ("'operator Short Name' propertie value is null.");
            throw new ConfigurationEPException ("'operator Short Name' propertie value is null.");
        }
        if (props.getProperty ("url")==null || props.getProperty ("url").equals ("")) {
            logger.error ("'url' propertie value is null.");
            throw new ConfigurationEPException ("'url' propertie value is null.");
        }
        if (props.getProperty ("login")==null || props.getProperty ("login").equals ("")) {
            logger.error ("'login' propertie value is null");
            throw new ConfigurationEPException ("'login' propertie value is null");
        }
        if (props.getProperty ("password")==null || props.getProperty ("password").equals ("")) {
            logger.error ("'password' propertie value is null");
            throw new ConfigurationEPException ("'password' propertie value is null");
        }
        if (props.getProperty ("encoding")==null || props.getProperty ("encoding").equals ("")) {
            logger.error ("'encoding' propertie value is null");
            throw new ConfigurationEPException ("'encoding' propertie value is null");
        }
        
        operatorShortName = props.getProperty ("operatorShortName");
        urlString = props.getProperty ("url");
        login = props.getProperty ("login");
        password = props.getProperty ("password");
        encoding = props.getProperty ("encoding","ISO-8859-1");
        
        PhoneAddress destinationPhone;
        if (!(envelope.getDestination () instanceof PhoneAddress)) { throw new ConfigurationEPException ("Destination is not a Phone Number"); }
        destinationPhone = (PhoneAddress) envelope.getDestination ();
        
        if (!destinationPhone.getAreaCode ().startsWith ("0")){
            destinatarios="0"+destinationPhone.getAreaCode () + destinationPhone.getLocal ();
        } else {
            destinatarios=destinationPhone.getAreaCode () + destinationPhone.getLocal ();
        }
        
        mensaje=envelope.getContent ().toString ();
        
        URLConnection con = this.getConnection (operatorShortName, urlString, login, password, encoding, mensaje, destinatarios);
        
        try {
            
            if (con instanceof HttpsURLConnection) {
                HttpsURLConnection conn = (HttpsURLConnection)con;
                X509TrustManager oTrustMngr = new HttpsX509TrustManager ();
                TrustManager oEnlistaTrustManagers[] = { oTrustMngr };
                SSLContext ctx = SSLContext.getInstance ("SSL");
                ctx.init (null, oEnlistaTrustManagers, null);
                SSLSocketFactory sf = ctx.getSocketFactory ();
                conn.setSSLSocketFactory (sf);
                conn.setHostnameVerifier (new HttpsHostNameVerifier ());
                
                conn.setDoInput (true);
                conn.setDoOutput (true);
                conn.setUseCaches (false);
                conn.setRequestMethod ("GET");
                InputStreamReader isr = new InputStreamReader (conn.getInputStream ());
                BufferedReader br = new BufferedReader (isr);
                String temp;
                while ((temp = br.readLine ()) != null) {
                    tempResponse = tempResponse + temp;
                }
                
                br.close ();
                isr.close ();
                conn.disconnect ();
            } else if (con instanceof HttpURLConnection) {
                HttpURLConnection conn = (HttpURLConnection)con;
                conn.setRequestMethod ("GET");
                InputStreamReader isr = new InputStreamReader (conn.getInputStream ());
                BufferedReader br = new BufferedReader (isr);
                String temp;
                while ((temp = br.readLine ()) != null){
                    tempResponse = tempResponse + temp;
                }
                br.close ();
                isr.close ();
                conn.disconnect ();
            }
        } catch (Throwable t) {
            throw new PeerEPException (operatorShortName,t);
        }
        
        if (!tempResponse.equals ("")){
            try {
                msg = "Submit sms response from "+operatorShortName+": Sequence number[" + envelope.getId () + "] Message status[" + 0+ "] Respuesta ["+tempResponse+"]";
                logger.info (msg);
                System.out.println (msg);
                //pdm.updateMDRStatus (Integer.parseInt (envelope.getId ()), 0);
            } catch (NumberFormatException e1) {
                logger.error (e1.getMessage ());
            } catch (Exception e1) {
                logger.error (e1.getMessage ());
            }
        }
        
        return envelope;
    }
    
    public void retrieveEnvelope (Object EnvelopeReference) throws CantHandException {
    }
    
    public void commitHandEnvelope (Object EnvelopeReference) throws CantHandException {
    }
}
